package IC.lir;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import IC.Constants;

/**
 * Represent ClassLayout Object
 * 
 */
public class LIRClassLayout {
	
	private LIRClass ClassRef;
	private Map<String, Integer> MethodOffsets;
	private Map<String, Integer> FieldOffsets;
	private LIRDv Dv;
	
	//C'tor
	public LIRClassLayout() {
		this.MethodOffsets = new LinkedHashMap<String, Integer>();
		this.FieldOffsets = new LinkedHashMap<String, Integer>();
		this.Dv = new LIRDv();
	}
	
	//Copy C'tor
	public LIRClassLayout(LIRClassLayout Cl) {
		this.MethodOffsets = new LinkedHashMap<String, Integer>(Cl.MethodOffsets);
		this.FieldOffsets = new LinkedHashMap<String, Integer>(Cl.FieldOffsets);
		this.Dv = new LIRDv(Cl.Dv.getMethods());
	}

	public void setClassRef(LIRClass ClassRef) {
		this.ClassRef = ClassRef;
		this.Dv.setClassRef(this.ClassRef);
	}
	
	public int size() {
		return 4*(FieldOffsets.size() + 1);
	}
	
	public void addField(String f) {
		FieldOffsets.put(f, FieldOffsets.size()+1);
	}
	
	public int getFieldOffset(String f) {
		return FieldOffsets.get(f);
	}
	
	public void addMethod(LIRMethod m) {
		if (!MethodOffsets.containsKey(m.getAstMethod().getName())) {
			// New:
			int offset = MethodOffsets.size();
			MethodOffsets.put(m.getAstMethod().getName(), offset);
			Dv.getMethods().put(offset, m);	
		} 
		else {
			// Override:
			int offset = getMethodOffset(m.getAstMethod().getName());
			Dv.getMethods().put(offset, m);
		}
	}
	
	public int getMethodOffset(String m) {
		return MethodOffsets.get(m);
	}
	
	public LIRMethod getLirMethod(String m) {
		return Dv.getMethods().get(getMethodOffset(m));
	}
	
	@Override
	public String toString() {
		StringBuffer s = new StringBuffer();
		
		if (!FieldOffsets.isEmpty()){
			s.append("## Fields Offsets ##" + Constants.LINE_BREAK);
			for (Entry<String, Integer> e : FieldOffsets.entrySet()) 
				s.append("## " + e.getKey() + " ==> " + e.getValue() + Constants.LINE_BREAK);
		}
		
		s.append(Dv);
		return s.toString();
	}
}
